const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const WebpackBar = require('webpackbar');
const Dotenv = require('dotenv-webpack');

const baseConfig = {
  entry: {
    index: path.resolve(__dirname, '../src/index.tsx'),
  },
  output: {
    filename: 'js/[name].[contenthash].js',
    path: path.resolve(__dirname, '../build'),
    publicPath: '/',
    clean: true,
    assetModuleFilename: 'assets/[hash][ext][query]',
  },
  optimization: {
    // 配置 optimization.moduleIds，让公共包 splitChunks 的 hash 不因为新的依赖而改变，减少非必要的 hash 变动
    moduleIds: 'deterministic',
    runtimeChunk: {
      name: 'runtimeChunk',
    },
    splitChunks: {
      chunks: 'all', // 可以选择对哪些chunk进行优化（all|async|initial）
      minSize: 30000, // 要生成的chunk的最小大小(b)
      maxSize: 1024 * 1024 * 2, // 把提取出来的模块打包生成的文件大小不能超过maxSize值，如果超过了，要对其进行分割并打包生成新的文件。单位为字节，默认为0，表示不限制大小。
      minChunks: 1, // 分割前必须共享模块的最小引用次数
      maxAsyncRequests: 6, // 按需加载 最大并行请求量
      maxInitialRequests: 4, // 初始化页面 最大并行请求量
      automaticNameDelimiter: '_', // chunk一般名称格式为（例如vendors_main.js）该项指分隔符
      cacheGroups: {
        // 缓存组可以继承和覆盖splitChunks.*全部属性
        'console-vendors': {
          chunks: 'initial',
          priority: -10, // 优先级
          reuseExistingChunk: true,
        },
        common: {
          name: `console-common`,
          priority: -20,
          chunks: 'initial',
          reuseExistingChunk: true,
        },
        // package: {
        //   test: /[\\/]node_modules[\\/]/,
        //   name(module) {
        //     const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
        //     return `package.${packageName.replace('@', '')}`;
        //   },
        // },
        default: false, // 将禁用默认缓存组
      },
    },
  },
  module: {
    rules: [
      {
        test: /\.html$/i,
        use: 'html-loader',
      },
      {
        test: /\.(js|jsx)$/i,
        use: 'babel-loader',
        exclude: /node_modules/,
      },

      {
        test: /\.(png|jfif|jpg|svg|webp)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.(woff2?|eot|ttf|otf)$/i,
        type: 'asset/inline',
      },
      {
        test: /\.(txt|conf)$/i,
        type: 'asset/source',
      },
      {
        test: /\.(ts|tsx)$/i,
        exclude: /node_modules/,
        use: ['ts-loader'],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, '../public/index.html'),
      scriptLoading: 'blocking',
      hash: true,
      inject: 'body',
      favicon: path.resolve(__dirname, '../src/assets/img/logo.svg'),
    }),
    new ESLintPlugin(),
    new WebpackBar({
      name: 'ax-cli',
      color: 'green',
    }),
    new Dotenv({
      path: path.resolve(__dirname, '../.env'),
    }),
  ],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, '../src'),
      '@@': path.resolve(__dirname, '../.'),
    },
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
  },
  /**
   * 防止将某些 import 的包(package)打包到 bundle 中，
   * 而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。
   */
  externals: {
    /**
     * key: value;
     *
     * 这里的key指的是 三方包的包名称
     * 这里的value指定的 三方包的CDN js文件链接中的全局变量(window的全局变量)
     */
    // moment: 'moment',
    // lodash: '_',
  },
};

module.exports = {
  baseConfig,
};
